#ifndef _timelog_c
#define _timelog_c

uns32 timeOn, timeLBL, timeLBH, timeHBL, timeHBH;

// Seconds
//	1	TBD
//	2	Write ON time
//	3	Write LBL time
//	4	Write LBH time
//	5	Write HBL time
//	6	Write HBH time

#define	ADDR_TIME_ON		0
#define	ADDR_TIME_ON_BK	5
#define	ADDR_TIME_LBL		10
#define	ADDR_TIME_LBL_BK	15
#define	ADDR_TIME_LBH		20
#define	ADDR_TIME_LBH_BK	25
#define	ADDR_TIME_HBL		30
#define	ADDR_TIME_HBL_BK	35
#define	ADDR_TIME_HBH		40
#define	ADDR_TIME_HBH_BK	45

bit timeOnDirty, timeOnBkDirty;
bit timeLBLDirty, timeLBLBkDirty;
bit timeLBHDirty, timeLBHBkDirty;
bit timeHBLDirty, timeHBLBkDirty;
bit timeHBHDirty, timeHBHBkDirty;
bit timerInit;

// Calls buffered and interrupt driven EEPROM write routine
// Also calculates and writes checksum
void tl_writeTimer( uns32 timer, char addr )
{
	ee_putchar( timer.high8, addr );
	ee_putchar( timer.midH8, ++addr );
	ee_putchar( timer.midL8, ++addr );
	ee_putchar( timer.low8, ++addr );
	ee_putchar( chk_generate( &timer, 4 ), ++addr );
}

// Calls EEPROM read routine on each byte of four byte timer
/// Returns checksum of timer
char tl_readTimer( uns32 *timer, char addr )
{
	*timer++ = ee_getchar( addr );
	*timer++ = ee_getchar( ++addr );
	*timer++ = ee_getchar( ++addr );
	*timer++ = ee_getchar( ++addr );
	return( ee_getchar( ++addr ) );
}

// Byte by byte copy from one four byte timer to another
void tl_copyTimer( uns32 *src, uns32 *dst )
{
	*src++ = *dst++;
	*src++ = *dst++;
	*src++ = *dst++;
	*src = *dst;
}

// Load timers from EEPROM
// Called routine checks for errors
// If a timer is corrupt its dirty bit is set
// If both timers are corrupt a Timer Fault should be logged (but isn't implimented yet)
void initTimers( void )
{
	timerInit = 1;
	tl_loadTimer( timeOn,  ADDR_TIME_ON,  ADDR_TIME_ON_BK,  &timeOnDirty,  &timeOnBkDirty );
	tl_loadTimer( timeLBL, ADDR_TIME_LBL, ADDR_TIME_LBL_BK, &timeLBLDirty, &timeLBLBkDirty );
	tl_loadTimer( timeLBH, ADDR_TIME_LBH, ADDR_TIME_LBH_BK, &timeLBHDirty, &timeLBHBkDirty );
	tl_loadTimer( timeHBL, ADDR_TIME_HBL, ADDR_TIME_HBL_BK, &timeHBLDirty, &timeHBLBkDirty );
	tl_loadTimer( timeHBH, ADDR_TIME_HBH, ADDR_TIME_HBH_BK, &timeHBHDirty, &timeHBHBkDirty );
}

// Load a timer from EEPROM
// If one copy is corrupt the other copy is used
// If both timers are good the greatest time is used

char tl_loadTimer( uns32 *timer, char mainAddr, char backAddr, bit *mainDirty, bit *backDirty )
{
	char chkMain, chkBack;
	uns32 main, back;
	
	chkMain = tl_readtimer( *main, mainAddr );
	chkBack = tl_readtimer( *back, backAddr );
	
	if( chkMain )
	{
		if( chkBack )
		{
			// both timers are corrupt
			*mainDirty = 1;
			*backDirty = 1;
			return( 0xff );
		}
		//Only Backup timer is good
		tl_copyTimer( &back, timer );
		*mainDirty = 1;
		*backDirty = 0;
		return( 0x0f );	
	}
	if( chkBack )
	{
		//Only Main timer is good
		tl_copyTimer( &main, timer );
		*mainDirty = 0;
		*backDirty = 1;
		return( 0xf0 );
	}
	
	//Both timers good, use highest time count
	if( main > back )
		tl_copyTimer( &main, timer );
	else
		tl_copyTimer( &back, timer );
		
	*mainDirty = 0;
	*backDirty = 0;

	return( 0 );
}



void tl_update()
{
	switch( seconds )
	{
		case 0:
			break;
			
		case 1:
			break;
			
		case 2:
			tl_writeTime( timeOn, ADDR_TIME_ON );
			break;	

		case 3:
			tl_writeTime( timeLBL, ADDR_TIME_LBL );
			break;	

		case 4:
			tl_writeTime( timeLBH, ADDR_TIME_LBH );
			break;	

		case 5:
			tl_writeTime( timeHBL, ADDR_TIME_HBL );
			break;	

		case 6:
			tl_writeTime( timeHBH, ADDR_TIME_HBH );
			break;	
			
		case 7:
			tl_writeTime( timeOn, ADDR_TIME_ON_BK );
			break;	

		case 8:
			tl_writeTime( timeLBL, ADDR_TIME_LBL_BK );
			break;	

		case 9:
			tl_writeTime( timeLBH, ADDR_TIME_LBH_BK );
			break;	

		case 10:
			tl_writeTime( timeHBL, ADDR_TIME_HBL_BK );
			break;	

		case 11:	// fall through this case on purpose
			tl_writeTime( timeHBH, ADDR_TIME_HBH_BK );
			break;	
				
		default:
			seconds = 0;
	}
}

void tl_incOn( void )
{
	timeOn++;
}


void incTime( TIME *time )
{
	if( time->seconds >= 59 )
	{
		time->seconds = 0;
		if( time->minutes >= 59 )
		{
			time->minutes = 0;
			if( time->hours < 255 )
			{
				time->hours++;
			}
		}
	}
}

void resetTime( TIME *time )
{
	time->seconds = 0;
	time->minutes = 0;
	time->hours   = 0;
}

void writeTime( TIME *time, char addr )
{
   ee_putchar( time->hours, addr );
   ee_putchar( time->minutes, ++addr );
   ee_putchar( time->seconds, ++addr );
   ee_putchar( chk_generate( time, 3 ), ++addr );
}



#endif
